/*
===========================================================================
This source file is part of DyLab (Dynamic Laboratory)
For the latest info, see http://dylab.googlecode.com

Copyright (c) 2006-2008 Lukas Krejci
(krejci.lukas@volny.cz)

This file is part of DyLab.

    DyLab is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    DyLab is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with DyLab.  If not, see <http://www.gnu.org/licenses/>.
===========================================================================
*/

#ifndef __dylab_Triangle_h__
#define __dylab_Triangle_h__

//===========================================================================================
#include <dylab/simobject/tetravol/Edge.h>
#include <dylab/utils/geometry/TriangleGeometry3.h>

//===========================================================================================
namespace dylab {

    /** This class represents the tetrahedral mesh triangle
	*/
    class DYLAB_EXPORT Triangle
    {
    public:
        typedef uint32_t id_t;

    protected:
        id_t mId;
        MassPoint * mMassPoints[TriangleGeometry3::V_COUNT];
        bool mIsBoundary;

    public:
        Triangle();
        Triangle(id_t _id, MassPoint * _mp0, MassPoint * _mp1, MassPoint * _mp2, bool _boundary);
        Triangle(id_t _id, MassPoint * (&_mp)[TriangleGeometry3::V_COUNT]);
        virtual ~Triangle();

        id_t getId() const
                { return mId; }

        MassPoint * getMassPoint(TriangleGeometry3::vertexidx_t _vertexIdx)
                { DYLAB_ASSERT(mMassPoints[_vertexIdx] != NULL);
                    return mMassPoints[_vertexIdx]; }
        const MassPoint * getMassPoint(TriangleGeometry3::vertexidx_t _vertexIdx) const
                { DYLAB_ASSERT(mMassPoints[_vertexIdx] != NULL);
                    return mMassPoints[_vertexIdx]; }

        bool isBoundary() const
                { return mIsBoundary; }
        void setBoundary(bool _boundary)
                { mIsBoundary = _boundary; }

        TriangleGeometry3 getGeometry() const
                { return TriangleGeometry3(getMassPoint(TriangleGeometry3::V_0)->currState().position, 
					getMassPoint(TriangleGeometry3::V_1)->currState().position, 
                    getMassPoint(TriangleGeometry3::V_2)->currState().position); }

        virtual Edge::id_t getEdgeID(TriangleGeometry3::edgeidx_t _edgeIdx) const;
    };            
    //-----------------------------------------------------------------------------

	//===========================================================================================
    class DYLAB_EXPORT TriangleContainer
        : public HashObjContainer<Triangle::id_t, Triangle>
    {
    public:
        TriangleContainer(bool _objectOwner)
            : HashObjContainer<Triangle::id_t, Triangle>(_objectOwner)
                { }
    };
    //-----------------------------------------------------------------------------

	//===========================================================================================
    class DYLAB_EXPORT TriangleList
        : public ListObjContainer<Triangle>
    {
    public:
        TriangleList(bool _objectOwner)
            : ListObjContainer<Triangle>(_objectOwner)
                { }
    };
    //-----------------------------------------------------------------------------
}
//===========================================================================================
#endif // __dylab_Triangle_h__
